package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.DmcRfidLabelOldmanMapper;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.model.constant.DeviceConstant;
import com.csun.cmny.provider.model.domain.*;
import com.csun.cmny.provider.model.dto.propertyManagement.SelectDeviceDataDto;
import com.csun.cmny.provider.model.dto.rfid.BindDmcRfidLabelOldmanDto;
import com.csun.cmny.provider.model.dto.rfid.RfidLabelPageQuery;
import com.csun.cmny.provider.model.enums.rfid.DmcRfidLabelRoleCodeEnum;
import com.csun.cmny.provider.model.vo.OpcUserVo;
import com.csun.cmny.provider.model.vo.propertyManagement.PropertyDataVo;
import com.csun.cmny.provider.model.vo.rfid.DmcRfidLabelVo;
import com.csun.cmny.provider.model.vo.OldmanBedRoomBuildingVo;
import com.csun.cmny.provider.model.vo.RfidLabelReqVo;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.*;
import com.csun.cmny.util.PublicUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Preconditions;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-01-21 20:54
 * @Description: the dmc rfid label oldman service impl
 */
@Service
public class DmcRfidLabelOldmanServiceImpl extends BaseService<DmcRfidLabelOldman>
        implements DmcRfidLabelOldmanService {

    @Resource
    private DmcRfidLabelOldmanMapper dmcRfidLabelOldmanMapper;

    @Resource
    private DmcDeviceService dmcDeviceService;
    @Resource
    private UacRpcService uacRpcService;
    @Resource
    private OmcRpcService omcRpcService;
    @Resource
    private CmnyMessageSource cmnyMessageSource;
    @Resource
    private DmcRfidLabelRoleService dmcRfidLabelRoleService;
    @Resource
    private DmcRfidEventService dmcRfidEventService;
    @Resource
    private DmcRfidEventOldmanService dmcRfidEventOldmanService;
    @Resource
    private DmcDeviceAlertService dmcDeviceAlertService;

    /**
     * bind dmc rfid label oldman
     *
     * @param bindDmcRfidLabelOldmanDto bind dmc rfid label oldman dto
     *
     * @return the int
     */
    @Override
    public Integer bindDmcRfidLabelOldman(BindDmcRfidLabelOldmanDto bindDmcRfidLabelOldmanDto) {

        Example example = new Example(DmcRfidLabelOldman.class);
        Example.Criteria criteria = example.createCriteria();

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceService
                .checkDeviceIsRfidLabelByDeviceId(bindDmcRfidLabelOldmanDto.getDeviceId());
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610018, bindDmcRfidLabelOldmanDto.getDeviceId());
        }

        // 绑定的角色是否存在
        Long roleId = bindDmcRfidLabelOldmanDto.getRoleId();
        Preconditions.checkArgument(roleId != null,
                cmnyMessageSource.getMessage("rfid.label.role.id.null", null));

        DmcRfidLabelRole dmcRfidLabelRole = dmcRfidLabelRoleService.selectByKey(roleId);
        if (PublicUtil.isEmpty(dmcRfidLabelRole)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100612003);
        }

        // 绑定角色的code是否合法
        DmcRfidLabelRoleCodeEnum roleEnum = DmcRfidLabelRoleCodeEnum.getEnum(dmcRfidLabelRole.getRoleCode());
        if (PublicUtil.isEmpty(roleEnum)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100612004);
        }
        switch (roleEnum.getKey()) {
            case DeviceConstant.RFID_ROLE_CODE_OLDMAN :
                // 校验老人
                Preconditions.checkArgument(bindDmcRfidLabelOldmanDto.getOldmanId() != null,
                        cmnyMessageSource.getMessage("rfid.label.own.id.null", null));
                OldmanBedRoomBuildingVo oldmanBedRoomBuildingVo = omcRpcService
                .queryOldmanBedRoomBuildingByOldmanId(bindDmcRfidLabelOldmanDto.getOldmanId().intValue());
                if (PublicUtil.isEmpty(oldmanBedRoomBuildingVo)) {
                    // 老人不存在
                    throw new DmcBizException(ErrorCodeEnum.DMC100610062);
                }
                bindDmcRfidLabelOldmanDto.setOldmanName(oldmanBedRoomBuildingVo.getOldmanName());
                break;
            case DeviceConstant.RFID_ROLE_CODE_EMP :
                // 校验员工
                Preconditions.checkArgument(bindDmcRfidLabelOldmanDto.getOldmanId() != null,
                        cmnyMessageSource.getMessage("rfid.label.own.id.null", null));
                OpcUserVo opcUserVo = uacRpcService.queryOpcUserVoByUserId(bindDmcRfidLabelOldmanDto.getOldmanId());
                if (PublicUtil.isEmpty(opcUserVo)) {
                    // 员工不存在
                    throw new DmcBizException(ErrorCodeEnum.UAC10011047);
                }
                break;
            case DeviceConstant.RFID_ROLE_CODE_OTHER :
                Preconditions.checkArgument(PublicUtil.isNotEmpty(bindDmcRfidLabelOldmanDto.getOldmanName()),
                        cmnyMessageSource.getMessage("rfid.label.own.name.null", null));
                break;
        }

        // 3.判断设备Id或者老人Id是否绑定过
        criteria.andEqualTo("deviceId", bindDmcRfidLabelOldmanDto.getDeviceId());
        example.or(example.createCriteria().andEqualTo("oldmanId", bindDmcRfidLabelOldmanDto.getOldmanId()));
        DmcRfidLabelOldman dmcRfidLabelOldman = dmcRfidLabelOldmanMapper.selectOneByExample(example);
        if (PublicUtil.isNotEmpty(dmcRfidLabelOldman)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610011, bindDmcRfidLabelOldmanDto.getDeviceId(),
                    dmcRfidLabelOldman.getOldmanId(), dmcRfidLabelOldman.getOldmanName());
        }

        // 4.绑定门禁卡标签和老人
        dmcRfidLabelOldman = new DmcRfidLabelOldman();
        BeanUtils.copyProperties(bindDmcRfidLabelOldmanDto, dmcRfidLabelOldman);
        Integer result = mapper.insertSelective(dmcRfidLabelOldman);

        return result;
    }

    /**
     * break dmc rfid label oldman
     *
     * @param deviceId device id
     *
     * @return the int
     */
    @Override
    public Integer breakDmcRfidLabelOldmanByDeviceId(Long deviceId) {

        // 1.判断设备Id是否存在
        DmcDevice dmcDevice = dmcDeviceService.checkDeviceIsRfidLabelByDeviceId(deviceId);
        if (PublicUtil.isEmpty(dmcDevice)) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610018, deviceId);
        }

        // 2.根据设备Id解绑
        Example example = new Example(DmcRfidLabelOldman.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("deviceId", deviceId);

        Integer result = dmcRfidLabelOldmanMapper.deleteByExample(example);

        /**
         * @date    2019-12-13
         * @author  chisj
         * @desc    解绑时清除门禁事件记录
         */
        if (result > 0) {
            dmcRfidEventOldmanService.deleteByLabelId(deviceId);

            dmcDeviceAlertService.deleteByDeviceId(deviceId);
        }

        return result;
    }

    /**
     * break dmc rfid label oldman by oldman id
     *
     * @param oldmanId  oldman id
     *
     * @return  the int
     */
    @Override
    public Integer breakDmcRfidLabelOldmanByOldmanId(Integer oldmanId) {

        // 1.根据老人Id解绑
        Example example = new Example(DmcRfidLabelOldman.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("oldmanId", oldmanId);

        Integer result = dmcRfidLabelOldmanMapper.deleteByExample(example);

        return result;
    }

    /**
     * query rfid label list with page
     *
     * @param rfidLabelPageQuery rfid label page query
     *
     * @return the page info.
     */
    @Override
    public PageInfo queryRfidLabelListWithPage(RfidLabelPageQuery rfidLabelPageQuery) {

        PageHelper.startPage(rfidLabelPageQuery.getPageNum(), rfidLabelPageQuery.getPageSize());

        List<DmcRfidLabelVo> dmcRfidLabelVoList = dmcRfidLabelOldmanMapper
                .queryRfidLabelListWithPage(rfidLabelPageQuery);

        return new PageInfo<>(dmcRfidLabelVoList);
    }

    /**
     * query rfid label by oldman id list
     *
     * @param oldmanIdList oldman id list
     * @return the list.
     */
    @Override
    public List<RfidLabelReqVo> queryRfidLabelByOldmanIds(List<Integer> oldmanIdList) {

        return dmcRfidLabelOldmanMapper.queryRfidLabelByOldmanIds(oldmanIdList);
    }

    /**
     * select rfid label by rfid label no
     *
     * @param labelNo the rfid label no
     *
     * @return the dmc rfid label vo
     */
    @Override
    public DmcRfidLabelVo selectByRfidLabelNo(String labelNo) {

        return dmcRfidLabelOldmanMapper.selectByRfidLabelNo(labelNo);
    }

    @Override
    public List<PropertyDataVo> selectDeviceData(SelectDeviceDataDto selectDeviceDataDto) {
        return dmcRfidLabelOldmanMapper.selectDeviceData(selectDeviceDataDto);
    }
}
